package enge.checkers;

import android.graphics.Color;
import android.graphics.Paint;
import java.util.Observable;

public class CheckerBoard
    extends Observable
{
    private int         boardColor1;
    private int         boardColor2;
    private Checker[][] board;
    private PlayerType  player1;
    private PlayerType  player2;
    private boolean     isPlayer1Turn;
    public boolean      jumped;
    public Checker      check;
    public boolean      isGameOver;
    private int         counterP1;
    private int         counterP2;
    public boolean		twoPlayer;


    public CheckerBoard(int c1, int c2, PlayerType p1, PlayerType p2)
    {
        board = new Checker[8][8];
        boardColor1 = c1;
        boardColor2 = c2;
        player1 = p1;
        player2 = p2;
        isPlayer1Turn = true;
        counterP1 = 12;
        counterP2 = 12;

        /**
         * Set's up initial visibility of the checkers on the board.
         */
        for (int x = 0; x < 8; x += 2)
        {
            board[x][0] = new Checker(true, PlayerType.TWO, false, x, 0, 0);
        }
        for (int x = 1; x < 8; x += 2)
        {
            board[x][1] = new Checker(true, PlayerType.TWO, false, x, 1, 0);
        }
        for (int x = 0; x < 8; x += 2)
        {
            board[x][2] = new Checker(true, PlayerType.TWO, false, x, 2, 0);
        }

        for (int x = 7; x >= 0; x = x - 2)
        {
            board[x][7] = new Checker(true, PlayerType.ONE, false, x, 7, 0);
        }
        for (int x = 6; x >= 0; x = x - 2)
        {
            board[x][6] = new Checker(true, PlayerType.ONE, false, x, 6, 0);
        }
        for (int x = 7; x >= 0; x = x - 2)
        {
            board[x][5] = new Checker(true, PlayerType.ONE, false, x, 5, 0);
        }
    }


    public Checker getChecker(int x, int y)
    {
        return board[x][y];
    }


    public boolean canPlayer1Move()
    {
        for (int x = 0; x < 8; x++)
        {
            for (int y = 0; y < 8; y++)
            {
                if (board[x][y] != null
                    && board[x][y].getPlayer().equals(PlayerType.ONE))
                {
                    for (int i = x - 2; i <= x + 2; i++)
                    {
                        for (int j = y - 2; j <= y + 2; j++)
                        {
                            if (i >= 0 && i < 8 && j < 8 && j >= 0
                                && checkPossible(getChecker(x, y), i, j))
                            {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }


    public boolean canPlayer2Move()
    {
        for (int x = 0; x < 8; x++)
        {
            for (int y = 0; y < 8; y++)
            {
                if (board[x][y] != null
                    && board[x][y].getPlayer().equals(PlayerType.TWO))
                {
                    for (int i = x - 2; i <= x + 2; i++)
                    {
                        for (int j = y - 2; j <= y + 2; j++)
                        {
                            if (i >= 0 && i < 8 && j < 8 && j >= 0
                                && checkPossible(board[x][y], i, j))
                            {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }


    public boolean checkGameOver()
    {
        counterP1 = 0;
        counterP2 = 0;
        for (int x = 0; x < 8; x++)
        {
            for (int y = 0; y < 8; y++)
            {
                if (board[x][y] != null)
                {
                    if (board[x][y].getPlayer() == PlayerType.ONE)
                    {
                        counterP1++;
                    }
                    if (board[x][y].getPlayer() == PlayerType.TWO
                        || board[x][y].getPlayer() == PlayerType.COMPUTER)
                    {
                        counterP1++;
                    }
                }
            }
        }
        if (counterP1 == 0 || counterP2 == 0)
        {
            isGameOver = true;
        }
        if (!canPlayer1Move() || !canPlayer2Move())
        {
            isGameOver = true;
        }
        return isGameOver;
    }


    public int getCounter1()
    {
        return counterP1;
    }


    public int getCounter2()
    {
        return counterP2;
    }


    public void setJumped(boolean f)
    {
        jumped = f;
    }


    public int getBoardColor1()
    {
        return boardColor1;
    }


    public int getBoardColor2()
    {
        return boardColor2;
    }


    public PlayerType getPlayer1()
    {
        return player1;
    }


    public PlayerType getPlayer2()
    {
        return player2;
    }


    public boolean getTurn()
    {
        return isPlayer1Turn;
    }


    public void changeTurn()
    {
        if (isPlayer1Turn)
        {
            isPlayer1Turn = false;
        }
        else
        {
            isPlayer1Turn = true;
        }
        jumped = false;
        setChanged();
        notifyObservers();
    }


    public Checker getPiece(int x, int y)
    {
        return board[x][y];
    }


    public void setPiece(int x, int y, Checker check)
    {
        board[x][y] = check;
    }


    public boolean checkPossible(Checker piece, int moveToX, int moveToY)
    {
        int arrayX = (int)piece.getX();
        int arrayY = (int)piece.getY();
        
        if (jumped && !board[arrayX][arrayY].equals(check))
        {
            return false;
        }
        System.out.println("x: " + arrayX);
        System.out.println("y: " + arrayY);
        /*
         * First Case: if player == Player 1
         */
        if (board[arrayX][arrayY] != null
            && (board[arrayX][arrayY].getPlayer().equals(PlayerType.ONE)))
        {
            /*
             * Case: Spot attempting to move to is not null AND piece at spot is
             * visible OR Spot attempting to move to is the same as the current
             * spot
             */
            if (board[moveToX][moveToY] != null
                && board[moveToX][moveToY].isVisible() || moveToX == arrayX)
            {
                return false;
            }
            /*
             * ELSE Case: Spot attempting to move to is 2 spots away, Y dir AND
             * absolute value of X direction movement == 2
             */
            else if (moveToY == arrayY - 2 && (Math.abs(moveToX - arrayX) == 2))
            {
                int middleX = (moveToX + arrayX) / 2;
                int middleY = (moveToY + arrayY) / 2;

                /*
                 * If piece jumped equals player 2 set to null
                 */
                if (board[middleX][middleY] != null
                    && board[middleX][middleY].getPlayer().equals(
                        PlayerType.TWO))
                {
                    check = board[arrayX][arrayY];
                    board[middleX][middleY] = null;
                    jumped = true;
                    System.out.println(jumped);
                    return true;
                }
            }

            /*
             * ELSE Case: attempted spot is 1 spot away AND abs of x direction
             * movement is 1
             */
            else if (moveToY == arrayY - 1 && (Math.abs(moveToX - arrayX) == 1)
                && !jumped)
            {
                return true;
            }

            /*
             * The test for the king (the piece can move the other direction).
             */
            else if (board[arrayX][arrayY].isKing())
            {
                if ((moveToY == arrayY + 2 && (Math.abs(moveToX - arrayX) == 2)))
                {
                    int middleX = (moveToX + arrayX) / 2;
                    int middleY = (moveToY + arrayY) / 2;

                    /*
                     * If piece jumped equals player 2 set to null
                     */
                    if (board[middleX][middleY].getPlayer().equals(
                        PlayerType.TWO))
                    {
                        board[middleX][middleY] = null;
                        jumped = true;
                        return true;
                    }
                }

                else if (moveToY == arrayY + 1
                    && (Math.abs(moveToX - arrayX) == 1) && !jumped)
                {
                    return true;
                }
            }

            return false;

        }

        /*
         * Case: player == player 2
         */
        if (board[arrayX][arrayY] != null
            && (board[arrayX][arrayY].getPlayer().equals(PlayerType.TWO)))
        {
            /*
             * Case: Attempted movement spot is not null AND piece at spot is
             * visible OR attempted spot is current spot
             */
            if (board[moveToX][moveToY] != null
                && board[moveToX][moveToY].isVisible() || moveToX == arrayX)
            {
                return false;
            }

            /*
             * ELSE Case: Spot is two forward in Y direction AND abs of X
             * movement is equal to 2
             */
            else if (moveToY == arrayY + 2 && (Math.abs(moveToX - arrayX) == 2))
            {
                int middleX = (moveToX + arrayX) / 2;
                int middleY = (moveToY + arrayY) / 2;

                /*
                 * Case: piece in middle equals player 1
                 */
                if (board[middleX][middleY] != null
                    && board[middleX][middleY].getPlayer().equals(
                        PlayerType.ONE))
                {
                    check = board[arrayX][arrayY];
                    board[middleX][middleY] = null;
                    jumped = true;
                    return true;
                }
            }

            /*
             * ELSE Case: if movement is 1 in both directions
             */
            else if (moveToY == arrayY + 1 && (Math.abs(moveToX - arrayX) == 1)
                && !jumped)
            {
                return true;
            }

            /*
             * ELSE if the piece is a king
             */
            else if (board[arrayX][arrayY].isKing())
            {
                if (moveToY == arrayY - 2 && (Math.abs(moveToX - arrayX) == 2))
                {
                    int middleX = (moveToX + arrayX) / 2;
                    int middleY = (moveToY + arrayY) / 2;

                    /*
                     * Case: piece in middle equals player 1
                     */
                    if (board[middleX][middleY].getPlayer().equals(
                        PlayerType.ONE))
                    {
                        board[middleX][middleY] = null;
                        jumped = true;
                        return true;
                    }
                }
                /*
                 * Else if move one space changes turn.
                 */
                else if (moveToY == arrayY - 1
                    && (Math.abs(moveToX - arrayX) == 1) && !jumped)
                {
                    return true;
                }
            }

            return false;

        }

        /*
         * ELSE Case: Movement in both directions = 1 AND player = 1
         */
        else if (board[arrayX][arrayY] != null
            && (board[arrayX][arrayY].getPlayer().equals(PlayerType.ONE))
            && (moveToY == arrayY - 1 && (moveToX == arrayX + 1 || moveToX == arrayX - 1))
            && !jumped)
        {
            return true;
        }
        /*
         * ELSE Case: Movement in both directions = 1 AND player = 1
         */
        else if (board[arrayX][arrayY] != null
            && (board[arrayX][arrayY].getPlayer().equals(PlayerType.TWO))
            && (moveToY == arrayY + 1 && (moveToX == arrayX + 1 || moveToX == arrayX - 1))
            && !jumped)
        {
            return true;
        }
        return false;
    }


    public boolean getJump()
    {
        return jumped;
    }


    public void computerMove()
    {
        for (int x = 0; x < 8; x++)
        {
            for (int y = 7; y >= 0; y--)
            {
                if (board[x][y] != null
                    && board[x][y].getPlayer() == PlayerType.TWO
                    && !board[x][y].isKing())
                {
                    if (y < 6 && x < 6 && board[x + 1][y + 1] != null
                        && board[x + 1][y + 1].getPlayer() == PlayerType.ONE
                        && board[x + 2][y + 2] == null)
                    {
                        board[x + 2][y + 2] = board[x][y];
                        if (y + 2 == 7)
                        {
                            board[x + 2][y + 2].setKing(true);
                        }
                        board[x + 1][y + 1] = board[x][y] = null;
                        update();
                        return;
                    }

                    else if (x > 1 && y < 6 && board[x - 1][y + 1] != null
                        && board[x - 1][y + 1].getPlayer() == PlayerType.ONE
                        && board[x - 2][y + 2] == null)
                    {
                        board[x - 2][y + 2] = board[x][y];
                        if (y + 2 == 7)
                        {
                            board[x - 2][y + 2].setKing(true);
                        }
                        board[x - 1][y + 1] = board[x][y] = null;
                        update();
                        return;
                    }
                }
                else if (board[x][y] != null
                    && board[x][y].getPlayer() == PlayerType.TWO
                    && board[x][y].isKing())
                {
                    for (int i = x - 2; i <= x + 2; i++)
                    {
                        for (int j = y - 2; j <= y + 2; j++)
                        {
                            if (i >= 0 && j >= 0 && i < 8 && j < 8
                                && checkPossible(board[x][y], i, j))
                            {
                                board[i][j] = board[x][y];
                                if (j == 7)
                                {
                                    board[i][j].setKing(true);
                                }
                                board[x][y] = null;
                                update();
                                return;
                            }
                        }
                    }
                }
            }
        }
        for (int x = 0; x < 8; x++)
        {
            for (int y = 7; y >= 0; y--)
            {
            	if (board[x][y] != null
                        && board[x][y].getPlayer() == PlayerType.TWO)
            	{
			        if (x < 7 && y < 7 && board[x + 1][y + 1] == null)
			        {
			            board[x + 1][y + 1] = board[x][y];
			            if (y + 1 == 7)
			            {
			                board[x + 1][y + 1].setKing(true);
			            }
			            board[x][y] = null;
			            update();
			            return;
			        }
			
			        else if (x > 0 && y < 7 && board[x - 1][y + 1] == null)
			        {
			            board[x - 1][y + 1] = board[x][y];
			            if (y + 1 == 7)
			            {
			                board[x - 1][y + 1].setKing(true);
			            }
			            board[x][y] = null;
			            update();
			            return;
			        }
	            }
	        }
        }
        //isGameOver = true;
    }


    public void update()
    {
        setChanged();
        notifyObservers();
    }
    
    public boolean getTwoPlayer()
    {
    	return twoPlayer;
    }
    
    public void setTwoPlayer(Boolean t)
    {
    	twoPlayer = t;
    }
}
